<!DOCTYPE html>
<html>

<head>
    <script>

// 1）子类的__proto__属性，表示构造函数的继承，总是指向父类。
// 2）子类prototype属性的__proto__属性，表示方法的继承，
//    总是指向父类的prototype属性
// 3) 子类实例的__proto__ 属性 等于 子类prototype属性
// 4) 子类实例的__proto__.__proto__  属性 等于 子类prototype.__proto__属性 等于 父类的 prototype属性

// class A{}
// class B extends A{}
// // 1）子类的__proto__属性，表示构造函数的继承，总是指向父类。
// B.__proto__===A;                                                   // true
// // 2）子类prototype属性的__proto__属性，表示方法的继承，
// //    总是指向父类的prototype属性
// B.prototype.__proto__===A.prototype;                            // true
// let b= new B();
// // 3) 子类实例的__proto__ 属性 等于 子类prototype属性
// b.__proto__===B.prototype;                                     // true
// // 4) 子类实例的__proto__.__proto__  属性 等于 子类prototype.__proto__属性 等于 父类的 prototype属性
// b.__proto__.__proto__===B.prototype.__proto__===A.prototype;  // true


class A0{
    getA0name(){return "szq0"}
}
class A extends A0{
    getAname(){return "szqA"}
}

console.log(A.__proto__===A0) // 指向父类A0 ，表示class的继承关系 (子类父类继承关系 静态方法直接继承)
console.log(A.prototype) // A.prototype是指A的构造器 以及公共函数 (类自己的原型)
console.log(A.prototype.__proto__===A0.prototype) // ===指向父类A0.prototype===是指A0的构造器 以及公共函数(父类的原型)


// 大多数浏览器的 ES5 实现之中，每一个对象都有__proto__属性，指向对应的类的构造函数的prototype属性。
let a=new A();
//a.__proto__ ===指向类A.prototype===是指A的构造器 以及公共函数(父类的)
console.log(a.__proto__===A.prototype.constructor.prototype===A.prototype);

// 这样实例a 就可以使用 A，A0 的原型链上的方法和属性了 -》a 就可以使用 A.protype中的getAname 和 A0.protype中的getA0name方法了。



        // let {log}=console;

        // class Person{ 
        //     constructor(){}
        //     #sex="man";
        //     get sex(){ return this.#sex;}
        //     set sex(value){this.#sex=value;}
        //     getSex(){return this.#sex;}
        // }

       

        // class Student extends Person{
        //     constructor(stuName,stuAge){
        //         super();
        //         this.stuName=stuName;
        //         this.stuAge=stuAge;
        //     }
        //     getstudentname(){return this.stuName;}
        // }
        // p1=new Person();
        // s1=new Student();
        // console.log(s1.__proto__===Student.prototype);

        // // s1.__proto__.__proto__ ===>Student.prototype.__proto__===>Person.prototype

        // // p1.__proto__===>Person.prototype 

        // // s1.__proto__.__proto__ ===> p1.__proto__
        // log(s1.__proto__.__proto__===p1.__proto__);

        // log(Person.prototype === p1.__proto__);

        // s1.__proto__.__proto__.getSex= function(){return "women";};
        // console.log(p1.getSex());
        



        // class A {
        //     static getname(){return "name"}
        // }

        // class B {
        // }
        // Object.setPrototypeOf = function (obj, proto) {
        //     obj.__proto__ = proto;
        //     return obj;
        // }


        // // B 的实例继承 A 的实例
        // Object.setPrototypeOf(B.prototype, A.prototype);

        // // B 继承 A 的静态属性
        // Object.setPrototypeOf(B, A);
        // log(B.getname());

        // const b = new B();

        // log(Reflect.getPrototypeOf(b)===B.prototype);
        // log(B.prototype);
        // log(A.prototype);


//         class Person{
//             constructor(){}
//             #sex="man";
//             get sex(){ return this.#sex;}
//             set sex(value){this.#sex=value;}
//             getSex(){return this.#sex;}
//         }


//         class Student extends Person{
//             constructor(stuName,stuAge){
//                 super();
//                 this.stuName=stuName;
//                 this.stuAge=stuAge;
//             }
//             getstudentname(){return this.stuName;}
//         }


//         log(Student.__proto__===Person);// （1）子类的__proto__属性，表示构造函数的继承，总是指向父类。 Person
//         log(Student.prototype.constructor===Student);// true

//         //某个类的prototype 包括它的构造方法，和公开方法
//         log(Student.prototype) // Student.constructor(stuName,stuAge) , Student.getstudentname   


// // C.prototype用于建立由 new C() 创建的对象的原型。
// // Object.getPrototype(obj)是ES5中用来获取obj对象的原型对象的标准方法。
// // obj.__proto__是获取obj对象的原型对象的非标准方法。

//         log(Person.prototype); //   Person.constructor,Person.getSex Person.sex
//         log(Object.getPrototypeOf(Person)); // ƒ () { [native code] }
//         log(Reflect.getPrototypeOf(Person));//ƒ () { [native code] }
//         log(Student.prototype.__proto__===Person.prototype)//2）子类prototype属性的__proto__属性，表示方法的继承，
//                                         //   总是指向父类的prototype属性  Person.constructor,Person.getSex
      
//         let stu=new Student("szq",11);
//         log(stu);
//         // stuAge: 11
//         // stuName: "szq"
//         // #sex: "man"
//         // sex: （…）
//         // [[Prototype]]: Person

//         log(stu.prototype);//undefined  C.prototype用于建立由 new C() 创建的对象的原型。

//          // 实例和父类 只有一条继承链
//         log(Reflect.getPrototypeOf(stu));
//         log(Reflect.getPrototypeOf(stu)===Student.prototype);
//         log(Reflect.getPrototypeOf(stu)===stu.__proto__);
//         // 2）子类prototype属性的__proto__属性，表示方法的继承，
//         //   总是指向父类的prototype属性  
//         log(stu.__proto__===Student.prototype);
//         // Person {constructor: ƒ, getstudentname: ƒ}
//         // constructor: class Student
//         // getstudentname: ƒ getstudentname()
//         // sex: （…）
//         // [[Prototype]]: Object
        
//         // 顶层 只有一条继承链
//         log(Person.prototype.__proto__===Object.prototype);



        


// // （1）子类的__proto__属性，表示构造函数的继承，总是指向父类。
// // （2）子类prototype属性的__proto__属性，表示方法的继承，总是指向父类的prototype属性
// class Animal {
 
//  constructor(name, age) {
//       //实例的私有属性
//      this.name = name
//      this.age = age
//      return console.log('实例属性')
//  }

//    test=['hello']  //实例私有属性，即使写在constructor外面，也是实例属性。

//  animalcall() {
//      console.log('Animalcall');
//  }

//  static animalAttr = 'Animal静态属性'

//  static animalStaFun() {
//      console.log('Animal静态方法');
//  }
// }
// // console.log(Animal.__proto__);
// // console.log(Animal.prototype);
// // console.log(Animal.prototype.__proto__===Object.prototype);
// // console.log(Object.prototype.__proto__)// null

// class Dog extends Animal {
//  constructor(name, age, color, weight) {
//      super(name, age)
//      this.color = color
//      this.weight = weight
//  }
//  dogcall(){ return "旺旺"}
// }

// （1）子类的__proto__属性，表示构造函数的继承，总是指向父类。
// console.log(Dog.__proto__);
// （2）子类prototype属性的__proto__属性，表示方法的继承，总是指向父类的prototype属性
//console.log(Dog.prototype); // dogcall 和 constructor(name, age, color, weight)
//  console.log(Dog.prototype.__proto__); // animalcall 和 constructor(name, age) ===Animal.prototype




// // 继承了Animal类的实例属性和实例方法
// let dog = new Dog('二狗', 1, 'black', '10kg')
// console.log(dog);
// dog.animalFun()
// // 继承Animal类的静态属性和静态方法
// console.log(Dog.animalAttr);
// Dog.animalStaFun()

// console.log(Dog.prototype.__proto__ === Animal.prototype);
// console.log(dog.__proto__.__proto__ === Animal.prototype);

// console.log(Dog.__proto__ === Animal);



//     function Star(uname, age) {
//         this.uname = uname;
//         this.age = age;
//     }
//     Star.prototype.sing = function () {
//         console.log('我会唱歌');
//     }
//     var ldh = new Star('刘德华', 18);
//     var zxy = new Star('张学友', 19);
//     ldh.sing();
//     console.log(ldh.__proto__); // 对象身上系统自己添加一个  __proto__指向我们构造函数的原型对象 prototype
//     console.log(ldh.__proto__ === Star.prototype);
// // 方法的查找规则: 首先先看ldh 对象身上是否有 sing 方法,如果有就执行这个对象上的sing
// // 如果么有sing 这个方法,因为有__proto__ 的存在,就去构造函数原型对象prototype身上去查找sing这个方法


        // class A {
        // }
        // class B extends A {
        // }
        // // （1）子类的__proto__属性，表示构造函数的继承，总是指向父类。
        // console.log(B.__proto__)
        // console.log(B.__proto__ === A) // true

        // // （2）子类prototype属性的__proto__属性，表示方法的继承，总是指向父类的prototype属性
        // console.log(B.prototype)
        // console.log(B.prototype.__proto__)
        // console.log(B.prototype.__proto__ === A.prototype)  // true
 
        // let b=new B();
        // console.log(b);
        // console.log(B.prototype.__proto__)
        // console.log(B.prototype)
        // class A {
        //     constructor() {
        //         // console.log(new.target.name);
        //     };
        //     p() { return "pppp"; };
        // }

        // class B extends A {
        //     constructor() {
        //         super();
        //         console.log(A);
        //         console.log(super.p());// super 当作为对象使用时作为A的原型对象 注意是对象；在静态方法中，指向父类。

        //     }
        // }
        // // new A() // A
        // new B() // B


        // class Foo {
        //     constructor() {
        //         console.log(this);
        //         console.log(this.#p)
        //     };
        //     #p = "22"; // 私有属性和方法无法被继承！
        //     #fun() {

        //         return "11"
        //     };
        // }

        // class Bar extends Foo {
        //     constructor() {
        //         // console.log(this); 此处报错
        //         super();
        //         console.log(this);

        //     }
        // }

        // const bar = new Bar();
        // console.log(bar);

        // console.log(bar instanceof Foo); // true
        // console.log(bar instanceof Bar); // true
        // console.log(typeof bar);
        // function myfun() { }
        // console.log(typeof myfun);



    </script>
</head>

<body>

</body>

</html>